#coding:utf-8

# 专有配置
# api 相关 sk   默认model
# 通用配置
# 生成的配置文件位置，从配置文件中获取激活api 信息列表
# 启用哪些激活的agent，默认应用连续对话？ 
# 配置哪些快捷键
# 是否持久化保留对话，是否加载历史会话，
## TODO 选中对话，导出为文本文件，或者是长截图？
# ! 侧边栏面板设计： 1.配置项 2.api agent 3.使用model 4. 切换 多轮会话/单轮会话
import sys
from typing import List
from PySide6.QtCore import Slot,QSettings
from PySide6.QtWidgets import QWidget,QGridLayout,QPushButton,QListWidget,QListWidgetItem,QApplication,QLabel,QCheckBox,QAbstractItemView,QLineEdit,QComboBox,QHBoxLayout
from qfluentwidgets import ComboBox
from agent import ModelMap
APIS = ["千问","混元","Kimi","千帆","豆包","DeepSeek"]

ktr = {"千问":"qw","混元":"hy","Kimi":"kimi","千帆":"qf","豆包":"db","DeepSeek":"ds"}
k2tr = {v:k  for k,v in ktr.items()}
NeedAK = {"千帆","豆包","混元"}

# from openai import OpenAI
# # for backward compatibility, you can still use `https://api.deepseek.com/v1` as `base_url`.
# client = OpenAI(api_key="<your API key>", base_url="https://api.deepseek.com")
# print(client.models.list())
class LabelLine(QWidget):
    def __init__(self, name:str,ctx:str,parent: QWidget ) -> None:
        super().__init__(parent)
        self.label = QLabel(self)
        self.label.setText(name)
        self.label.setMaximumWidth(50)
        self.line =QLineEdit(self)
        if ctx:
            self.line.setText(ctx)
        hb = QHBoxLayout(self)
        hb.addWidget(self.label,1)
        hb.addWidget(self.line,4)
        self.setLayout(hb)
    def text(self):
        return self.line.text()
    

class Item(QWidget):
    def __init__(self, parent: QWidget,name,sk,model:List[str],ak=None,use=None) -> None:
        super().__init__(parent)
        self.name = QLabel(self)
        self.name.setText(name)
        self.name.setMaximumWidth(40)
        self.sk = LabelLine("sk",sk,self)
        self.ak = LabelLine("ak",ak,self)if not ak is None  else None
        if name =="豆包" and len(model)!=1:
            raise ValueError("豆包model项也是一个控制台生成值，请访问火山模型控制台创建")
        self.hb = QHBoxLayout()
        self.hb.addWidget(self.name,1)
        self.hb.addWidget(self.sk,3)
        if not self.ak is None:
            self.hb.addWidget(self.ak,3)
        if name!="豆包":
            self.model = QComboBox(self)
            self.model.addItems(model)
            self.model.setCurrentText(use if use else "无")
            self.hb.addWidget(self.model,1)
        else:
            self.model = LabelLine("model",model[0],self)
            
            self.hb.addWidget(self.model,1)
        self.setLayout(self.hb)
    def getConfig(self):
        if not self.name.text() in NeedAK: 
            return {"name":self.name.text(),"sk":self.sk.text(),"model":self.model.currentText() } # type: ignore
        return {"name":self.name.text(),"sk":self.sk.text(),"ak":self.ak.text() if self.ak else "","model":self.model.currentText() if self.name.text()!="豆包" else self.model.text()} # type: ignore

class ConfigView(QWidget):
    def __init__(self,pa,ags,da ) -> None:
        super().__init__(pa)
        self.resize(800,450)
        self.glb = QLabel("全局配置",self)
        self.glb.setMaximumHeight(30)
        self.glb.setText("全局配置")
        self.useMulti = QCheckBox("启用连续对话",self)
        self.useMulti.setMaximumHeight(30)
        self.saveHistory =QCheckBox("保存历史会话",self)
        self.saveHistory.setMaximumHeight(30)
        self.addButton = QPushButton(self)
        self.addButton.setText("<<")
        self.addButton.setMaximumWidth(40)
        self.addButton.clicked.connect(self.addList)
        self.removeButton =QPushButton(self)
        self.removeButton.setText(">>")
        self.removeButton.setMaximumWidth(40)
        self.removeButton.clicked.connect(self.removeList)
        self.applyButton =QPushButton("应用",self)
        self.applyButton.clicked.connect(self.applyConfig)
        self.useList = QListWidget(self)
        self.useList.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection)
        self.useset = set()
        self.useList.setStyleSheet("QListWidget::item{background-color : #ffffff;color: #000000;border: transparent;border-bottom: 1px solid #dbdbdb;}QListView::item:selected{border: 2px solid gray;background : lightblue;}")
        self.supportList = QListWidget()
        self.supportList.setMinimumWidth(20)
        self.initSupportList()
        self.api = QLabel("api配置",self)
        self.api.setText("api配置")
        self.api.setMaximumHeight(30)
        self.configDir = "./"
        self.lda = QLabel(self)
        self.lda.setText("使用模型:")
        self.card = ComboBox()
        self.card.addItems([x for x in ags.keys()])
        self.card.setCurrentText(da)
        self.la = QGridLayout(self)
        self.la.addWidget(self.glb,0,0,1,2)
        self.la.addWidget(self.useMulti,1,1,1,1)
        self.la.addWidget(self.saveHistory,2,1,1,1)
        self.la.addWidget(self.lda,3,0,1,6)
        self.la.addWidget(self.card,3,2,1,6)
        self.la.addWidget(self.api,4,0,1,2)
        self.la.addWidget(self.useList,5,0,5,6)
        self.la.addWidget(self.addButton,6,6,1,1)
        self.la.addWidget(self.removeButton,8,6,1,1)
        self.la.addWidget(self.supportList,5,7,5,2)
        self.la.addWidget(self.applyButton,10,8,1,1)
        
        self.la.setColumnMinimumWidth(7,30)
        self.la.setColumnMinimumWidth(8,30)
        self.setLayout(self.la)
        self.loadConfig()

        
    def initSupportList(self):
        
        self.supportList.addItems(APIS)
        self.supportList.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection)
        self.supportList.setStyleSheet("QListWidget::item{background-color : #ffffff;color: #000000;border: transparent;border-bottom: 1px solid #dbdbdb;padding: 8px;}QListView::item:selected{border : 2px solid gray;background : lightblue;}")
    def addList(self,l:List[str]):
        for s in  self.supportList.selectedItems():
            if s.text() not in self.useset:
                self.addNewItem(s.text(),sk="",model=ModelMap[s.text()],ak="" if s.text() in NeedAK else None)
    def removeList(self,l:List[str]):
        for s in self.useList.selectedItems():
            val = self.useList.itemWidget(s)
            self.useList.removeItemWidget(s)
            self.useList.takeItem(self.useList.row(s))
            self.useset.remove(val.name.text()) # type: ignore




    @Slot()
    def applyConfig(self):
        seting = QSettings(os.path.join(self.configDir,"config.ini"),QSettings.Format.IniFormat)
        seting.beginGroup("global")
        seting.setValue("MULTI","false" if not self.useMulti.isChecked() else "true")
        seting.setValue("historysave","false" if not self.saveHistory.isChecked() else "true")
        seting.setValue("da",self.card.currentText())
        seting.endGroup()
        for i in range(self.useList.count()):
            s = self.useList.item(i)
            val = self.useList.itemWidget(s)
            info = val.getConfig() # type: ignore
            n = info["name"]
            for k,v in info.items():
                if k!="name":
                    seting.setValue(f"{ktr[n]}/{k}",v)


    def loadConfig(self):
        seting = QSettings(os.path.join(self.configDir,"config.ini"),QSettings.Format.IniFormat)
        isMulti = seting.value("global/MULTI",type=bool)
        if isMulti:
            self.useMulti.setChecked(True)
        isSaveHistory = seting.value("global/historysave",type=bool)
        if isSaveHistory:
            self.saveHistory.setChecked(True)
        for v in k2tr:
            if seting.value(f"{v}/sk",type=str) and  seting.value(f"{v}/model",type=str):
                if v in NeedAK and seting.value(f"{v}/ak",type=str):
                    self.addNewItem(k2tr[v],seting.value(f"{v}/sk",type=str),model=ModelMap[k2tr[v]],use=[seting.value(f"{v}/model",type=str)],ak=seting.value(f"{v}/model",type=str))
                else:
                    self.addNewItem(k2tr[v],seting.value(f"{v}/sk",type=str),model=ModelMap[k2tr[v]],use=[seting.value(f"{v}/model",type=str)])

    def addNewItem(self,v,sk,model,ak=None,use=None):
        temp = QListWidgetItem(self.useList)
        item = Item(self.useList,name=v,sk=sk,model=model,ak=ak)
        temp.setSizeHint(item.sizeHint())
        self.useList.addItem(temp)
        self.useList.setItemWidget(temp,item)
        self.useset.add(v)
from agent import openai,hy,qf,db,auth    


def buildQF(sk,ak,model):
    a = qf(sk=sk,ak=ak)
    a.setModel(model)
    return a
def buildHY(sk,ak,model):
    a = hy(sk=sk,ak=ak)
    a.setModel(model)
    return a
def buildDB(sk,ak,model):
    a = db(sk,ak)
    a.setModel(model)
    return a

closeai = {"混元":buildHY,"千帆":buildQF,"豆包":buildDB}

import os
def builder(dir:str):
    seting = QSettings(os.path.join(dir,"config.ini"),QSettings.Format.IniFormat)
    global isMulti,saveHistory
    if seting.value("global/isMulti",type=bool):
        isMulti = True
    if seting.value("global/saveHistory",type=bool):
        saveHistory = True


    ret = dict()
    for v in k2tr:
        vt = k2tr[v]
        if not vt in NeedAK:
            if seting.value(f"{v}/sk",type=str) and  seting.value(f"{v}/model",type=str):
                a = openai(auth(sk=seting.value(f"{v}/sk",type=str),type=vt))
                a.setModel(seting.value(f"{v}/model",type=str)) # type: ignore
                ret[vt] = a
        else:
            if seting.value(f"{v}/sk",type=str) and seting.value(f"{v}/ak",type=str) and  seting.value(f"{v}/model",type=str):
                ret[vt] = closeai[v](sk=seting.value(f"{v}/sk",type=str),ak=seting.value(f"{v}/ak",type=str),model=seting.value(f"{v}/model",type=str))
    return ret, seting.value("global/da",type=str) if seting.value("global/da",type=str) else None

if __name__ =="__main__":
    app =QApplication()
    widget = ConfigView(None,{"":""},da="")
    widget.show()
    app.exec()
    sys.exit(0)    


